package com.sccl.autojob.util.convert;

import com.google.gson.JsonObject;
import com.sccl.autojob.application.domain.TaskAttributes;
import com.sccl.autojob.skeleton.tq.Task;
import com.sccl.autojob.util.AutoJobUtil;
import com.sccl.autojob.util.id.IdGenerator;
import lombok.Data;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description 任务参数构建类
 * @Auther Huang Yongxiang
 * @Date 2022/01/25 15:42
 */
@Data
public class TaskAttributesUtil {
    public enum AttributesType {
        /**
         * 字符串类型
         */
        STRING("string"),
        /**
         * 定点数类型，对应java的BigDecimal包装类型
         */
        DECIMAL("decimal"),
        /**
         * 浮点数类型，对应java的Double包装类型
         */
        DOUBLE("double"),
        /**
         * 整数类型，对应java的Integer包装类型
         */
        INTEGER("integer"),
        /**
         * 长整型，对于java的Long包装类型
         */
        LONG("long"),
        /**
         * 布尔类型，对应java的Boolean包装类型
         */
        BOOLEAN("boolean");
        private final String value;

        AttributesType(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }
    }

    /**
     * 基本类型
     */
    private AttributesType attributesType;
    /**
     * 对象类型
     */
    private Class<?> attributesObjectType;
    /**
     * 参数值
     */
    private Object values;

    protected TaskAttributesUtil() {
    }

    public static TaskAttributesUtil build(AttributesType attributesType, Object values) {
        TaskAttributesUtil taskAttributesUtil = new TaskAttributesUtil();
        taskAttributesUtil.setAttributesType(attributesType);
        taskAttributesUtil.setValues(values);
        return taskAttributesUtil;
    }

    public static TaskAttributesUtil build(Class<?> attributesObjectType, Object values) {
        TaskAttributesUtil taskAttributesUtil = new TaskAttributesUtil();
        taskAttributesUtil.setAttributesObjectType(attributesObjectType);
        taskAttributesUtil.setValues(values);
        return taskAttributesUtil;
    }


    public String valueOf() {
        if (attributesType == null && attributesObjectType == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();

        if (attributesObjectType == null) {
            map.put("type", attributesType.value);
            Map<String, Object> value = new HashMap<>();
            value.put("value", values);
            map.put("values", value);
        } else {
            map.put("type", attributesObjectType.getName());
            map.put("values", values);
        }
        return JsonUtil.getMapJson(map);
    }

    public static String getValue(AttributesType attributesType, Object values) {
        if (attributesType == null) {
            return null;
        }
        List<Map<String, Object>> list = new LinkedList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("type", attributesType.value);
        Map<String, Object> value = new HashMap<>();
        value.put("value", values);
        map.put("values", value);
        list.add(map);
        return JsonUtil.getJson(list);
    }

    public static String getValue(Class<?> attributesObjectType, Object values) {
        if (attributesObjectType == null) {
            return null;
        }
        List<Map<String, Object>> list = new LinkedList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("type", attributesObjectType.getName());
        map.put("values", values);
        list.add(map);
        return JsonUtil.getJson(list);
    }

    public static TaskAttributes valueOf(String taskAttributesString) {
        try {
            JsonObject jsonObject = JsonUtil.stringToJsonObj(taskAttributesString);
            String startTime = jsonObject.get("startTime") == null ? null : jsonObject.get("startTime").getAsString();
            if (!StringUtils.isEmpty(startTime)) {
                Date date = ConvertUtil.convertDate(startTime, "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH-mm-ss", "yyyy/MM/dd " + "HH:mm:ss", "yyyy.MM.dd HH:mm:ss", "yyyy");
                if (date == null) {
                    return null;
                }
                startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
            }

            Long id = jsonObject.get("id") == null ? null : jsonObject.get("id").getAsLong();

            String methodClassName = jsonObject.get("methodClass") == null ? null : jsonObject.get("methodClass").getAsString();

            String attributes = jsonObject.get("attributes") == null ? null : jsonObject.get("attributes").getAsString();

            String type = jsonObject.get("type") == null ? null : jsonObject.get("type").getAsString();

            String methodNameString = jsonObject.get("methodName") == null ? null : jsonObject.get("methodName").getAsString();
            long circle = jsonObject.get("circle") == null ? 0 : jsonObject.get("circle").getAsLong();
            int repeatTimes = jsonObject.get("repeatTimes") == null ? 1 : jsonObject.get("repeatTimes").getAsInt();

            boolean isEndurance = jsonObject.get("isEndurance") == null || jsonObject.get("isEndurance").getAsBoolean();
            TaskAttributes taskAttributes = new TaskAttributes();
            taskAttributes.setAttributes(attributes);
            taskAttributes.setId(id);
            taskAttributes.setCircle(circle);
            taskAttributes.setIsEndurance(isEndurance);
            taskAttributes.setMethodClassName(methodClassName);
            taskAttributes.setMethodName(methodNameString);
            taskAttributes.setRepeatTimes(repeatTimes);
            taskAttributes.setStartTime(startTime);
            if (!StringUtils.isEmpty(type)) {
                if ("FOR_LAST_TASK".equalsIgnoreCase(type)) {
                    taskAttributes.setType(Task.TaskType.FOR_LAST_TASK);
                } else {
                    taskAttributes.setType(Task.TaskType.FOR_NOW_TASK);
                }
            }
            return taskAttributes;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Task parseTaskAttribute(TaskAttributes taskAttributes) {
        if (taskAttributes == null) {
            return null;
        }
        Task task = new Task();
        task.setId(taskAttributes.getId() == null ? IdGenerator.getNextIdAsLong() : taskAttributes.getId());
        task.setStartTime(StringUtils.isEmpty(taskAttributes.getStartTime()) ? DateUtils.getDateTime() : taskAttributes.getStartTime());
        task.setRepeatTimes(taskAttributes.getRepeatTimes() == null ? 1 : taskAttributes.getRepeatTimes());
        Class<?> type = ConvertUtil.classNameToClass(taskAttributes.getMethodClassName());
        task.setMethodClass(type);
        task.setMethodName(taskAttributes.getMethodName());
        task.setType(taskAttributes.getType() == null ? Task.TaskType.FOR_NOW_TASK : taskAttributes.getType());
        task.setMethodClassName(taskAttributes.getMethodClassName());
        task.setObjectAttributes(AutoJobUtil.convertAttributes(taskAttributes.getAttributes()));
        task.setAttributes(taskAttributes.getAttributes());
        task.setIsEndurance(taskAttributes.getIsEndurance() != null && taskAttributes.getIsEndurance());
        task.setCircle(taskAttributes.getCircle() == null ? 0 : taskAttributes.getCircle());
        task.setIsStarted(0);
        task.setKind(0);
        task.setIsFinished(0);
        return task;
    }


    /**
     * 使用注解模式时可以编写该方法得到参数值，然后复制到注解里，避免手写json导致语法错误
     *
     * @return void
     * @author Huang Yongxiang
     * @date 2022/1/25 16:34
     */
    public static void main(String[] args) {
        Task task = new Task();
        task.setId(123L);
        task.setMethodName("45");
        TaskAttributesUtil taskAttributesUtil = TaskAttributesUtil.build(Task.class, task);
        System.out.println(taskAttributesUtil.valueOf());
        System.out.println(TaskAttributesUtil.getValue(AttributesType.STRING, "xuli"));
    }

}
